#ifndef DYNAMIC_PROPERTY_H
#define DYNAMIC_PROPERTY_H

#include "detail/dynamic_property_impl.h"
namespace vpm 
{
	namespace utils
	{		
		using namespace detail;

		template <class KeyT = std::string > 
		class DynamicProperty
		{
		public:

			DynamicProperty()
			{

			}

			DynamicProperty(const KeyT & n1 )
			{
				m_propertyImpl.set_mandatory_property(n1);
			}

			DynamicProperty(const KeyT & n1 ,const KeyT & n2)
			{
				m_propertyImpl.set_mandatory_property(n1);
				m_propertyImpl.set_mandatory_property(n2);
			}

			DynamicProperty(const KeyT & n1 ,const KeyT & n2,const KeyT & n3)
			{
				m_propertyImpl.set_mandatory_property(n1);
				m_propertyImpl.set_mandatory_property(n2);
				m_propertyImpl.set_mandatory_property(n3);
			}

			DynamicProperty(const KeyT & n1 ,const KeyT & n2,const KeyT & n3,const KeyT & n4)
			{
				m_propertyImpl.set_mandatory_property(n1);
				m_propertyImpl.set_mandatory_property(n2);
				m_propertyImpl.set_mandatory_property(n3);
				m_propertyImpl.set_mandatory_property(n4);
			}

			DynamicProperty(const KeyT & n1 ,const KeyT & n2,const KeyT & n3,const KeyT & n4,const KeyT & n5)
			{
				m_propertyImpl.set_mandatory_property(n1);
				m_propertyImpl.set_mandatory_property(n2);
				m_propertyImpl.set_mandatory_property(n3);
				m_propertyImpl.set_mandatory_property(n4);
				m_propertyImpl.set_mandatory_property(n5);
			}

			template <class ValueT> 
			void set_property( const KeyT & n , ValueT  v)
			{
				m_propertyImpl.set_property<ValueT>(n, v);
			}

			template <class ValueT> 
			void set_property_value( const KeyT & n , ValueT  v,boost::function<void(ValueT)> op)
			{
				m_propertyImpl.set_property_value<ValueT>(n, v,op);
			}

			template <class ValueT>
			void set_property( const KeyT & n , ValueT  v,boost::function<void(const KeyT&,ValueT)> op)
			{
				m_propertyImpl.set_property<ValueT>(n, v,op);
			}

			template <class ValueT> 
			ValueT get_property(const KeyT & n)
			{
				return m_propertyImpl.get_property<ValueT>(n);
			}

			void set_mandatory_property(const KeyT & n)
			{
				m_propertyImpl.set_mandatory_property(n);
			}

			bool check_mandatory_properties()
			{
				return m_propertyImpl.check_mandatory_properties();
			}

		private:
			DynamicPropertyImpl<KeyT> m_propertyImpl; 
		};

	}
}

#endif // 

